//
//  DownloadBaseModel.m
//  TravelGuideHD
//
//  Created by BigPolarBear on 9/1/14.
//  Copyright (c) 2014 mafengo Inc. All rights reserved.
//

#import "DownloadBaseModel.h"
#import "MFWDownloadManager.h"
#import "NetStatusManager.h"
#import "CacheDB.h"
#import "FMDatabase.h"
#import "ConstPath.h"
#import "DBHelper.h"
#import "DBEngine.h"

//------------------------------------------------- 只会在子类内部使用的状态 start

/** 细化状态之：下载状态（只用于接口返回结果） */
typedef enum {
    ItemDownloadStatusNotExist      = 100,     // 未下载
    ItemDownloadStatusFinished      = 101,     // 已下载
	ItemDownloadStatusDownloading   = 102,     // 下载中
    ItemDownloadStatusWaiting       = 103,     // 等待中
    ItemDownloadStatusPaused        = 104,     // 暂停
    ItemDownloadStatusError         = 105      // 出错
} ItemDownloadStatus;

/**
 细化状态之：磁盘上的完成状态（会被持久化到数据库使用）
 
 @attention：如有变更，必须同步更新客户端数据库设计文档!!!
 
 */
typedef enum {
    ItemFinishStatusNotExist    = 0,   // 不存在
    ItemFinishStatusFinished    = 1,   // 已完成
    ItemFinishStatusNotFinished = 2,   // 未完成
    ItemFinishStatusMustUpdate  = 3,   // 必须更新（来自老用户升级，由于之前以下载的PDF不再支持，故所有已下载的PDF在新的库中的完成状态都是这个）
    ItemFinishStatusError       = 4    // 出错
} ItemFinishStatus;
//------------------------------------------------- 只会在子类内部使用的状态 end



@interface DownloadBaseModel()

// @Attection 要先判断[完成状态]！！只有未完成的攻略，取[下载状态]和[下载百分比]才有意义

/** Step 1 : 攻略完成状态（不存在、未完成、已完成、必须更新）*/
-(ItemFinishStatus)itemFinishStatus:(NSString*)itemId;
/** Step 2 : 攻略下载状态 */
-(ItemDownloadStatus)itemDownloadStatus:(NSString*)itemId;

@end


@implementation DownloadBaseModel

+(instancetype)defaultModel
{
    static dispatch_once_t pred;
    static NSMutableDictionary* _sharedInstance;
    dispatch_once(&pred, ^{
        _sharedInstance = [[NSMutableDictionary alloc] init];
    });
    
    
    NSString* className = NSStringFromClass([self class]);
    id retModel = nil;
    retModel = [_sharedInstance objectForKey:className];
    if (!retModel) {
        retModel = [[self alloc] init];
        [_sharedInstance setObject:retModel forKey:className];
    }
    
    return retModel;
}

-(MFWDownloadManager*)downloadManager
{
    return [MFWDownloadManager managerNamedCatalog:NSStringFromClass([self class])];
}

-(id)init
{
    self = [super init];
    if (self) {
        [[self downloadManager] resume];
        // 监听下载事件
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(handlerNotificationDownloadChanged:)
                                                     name:MFW_DOWNLOAD_STATE_CHANGE_NOTIFY
                                                   object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(handlerNotificationPercentChanged:)
                                                     name:MFW_DOWNLOAD_PERCENT_CHANGE_NOTIFY
                                                   object:nil];
    }
    return self;
}

#pragma mark 用户的下载策略
#define itemDownloadPolicyKey @"ItemDownloadPolicyKey"
- (ItemDownloadPolicy)itemDownloadPolicy
{
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    if ([def objectIsForcedForKey:itemDownloadPolicyKey])
    {
        return [def integerForKey:itemDownloadPolicyKey];
    }
    else
    {
        return ItemDownloadPolicyAlwaysAsk;
    }
}

- (void)setItemDownloadPolicy:(ItemDownloadPolicy)itemDownloadPolicy
{
    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];
    [def setInteger:itemDownloadPolicy forKey:itemDownloadPolicyKey];
    [def synchronize];
}


#pragma mark ------------------------- 子类重写：必须

-(Class)classOfItem
{
#ifdef DEBUG
    NSAssert(NO, @"未重写classOfItem");
#endif
    return nil;
}

-(NSString*)downloadTableName
{
#ifdef DEBUG
    NSAssert(NO, @"未重写downloadTableName");
#endif
    return @"";
}
-(BaseItemWithDownload*)cacheCenterItemById:(NSString*)itemId
{
#ifdef DEBUG
    NSAssert(NO, @"未重写cacheCenterItemById");
#endif
    return nil;
}

/** 安装已下载的包 */
-(void)startInstallItemWithId:(NSString*)itemId
                   completion:(void(^)(BOOL success, NSError *error))completion
{
#ifdef DEBUG
    NSAssert(NO, @"未重写startInstallItemWithId:completion:");
#endif
}

/** 根据id数组，获取最新数据（获取完成后，确保通过cacheCenterItemById:可以取出来） */
-(void)requestListByIds:(NSArray*)ids
             completion:(void(^)(NSArray* listItem))completion
{
#ifdef DEBUG
    NSAssert(NO, @"未重写requestListByIds:completion:");
#endif
}



#pragma mark ------------------------- 子类重写（暂时不开放子类重写）
-(NSDictionary*)dbExtraDict:(BaseItemWithDownload*)item
{
//    BaseItemWithDownload* bookItem = (id)item;
//    if ([bookItem isKindOfClass:[BaseItemWithDownload class]]) {
//        return  @{kTableColumn_base_down_title:bookItem.title};
//    }else{
//        return nil;
//    }
    return nil;
}


#pragma mark 子类可选择重写：文件路径
/**
 item所属文件夹： 主路径/子路径（与itemId相关）/
 */
-(NSString*)downloadPath:(NSString*)itemId
{
    return [NSString stringWithFormat:@"%@/%@",[self downloadPathMain],[self downloadPathSub:itemId]];
}

/**
 下载的item文件全路径：主路径/子路径（与itemId相关）/下载文件名
 */
-(NSString*)downloadPathFile:(NSString*)itemId
{
    return [NSString stringWithFormat:@"%@/%@",[self downloadPath:itemId],[self downloadFileName:itemId]];
}

/** 主路径 */
-(NSString*)downloadPathMain
{
#ifdef DEBUG
    NSAssert(NO, @"未重写downloadPathMain");
#endif
    return nil;
}

/** 子路径（与itemId相关） */
-(NSString*)downloadPathSub:(NSString*)itemId
{
    return itemId;
}

/** 下载文件名 */
-(NSString*)downloadFileName:(NSString*)itemId
{
    return @"pkg.zip";
}


#pragma mark ------------------------- 暂时无需重写
#pragma mark 通知相关
/** 通知：下载实例状态变化 */
+(NSString*)notificationOfItemStatusChanged
{
    return [NSString stringWithFormat:@"notificationOfItemStatusChanged_%@",NSStringFromClass([self class])];
}
/** 通知：下载进度变化 */
+(NSString*)notificationOfDownloadPercentChanged
{
    return [NSString stringWithFormat:@"notificationOfDownloadPercentChanged_%@",NSStringFromClass([self class])];
}
/** 通知：下载队列新增 */
+(NSString*)notificationOfDownloadAdded
{
    return [NSString stringWithFormat:@"notificationOfDownloadAdded_%@",NSStringFromClass([self class])];
}

#pragma mark 网络状态相关
// 开始监听网络状态 自动运行
- (void)startListenNetWorkAndAutoRun
{
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(networkStateChange:)
                                                 name:kNotification_NetworkStatusChanged
                                               object:nil];
}

// 停止监听网络状态
- (void)stopListenNetWorkAndAutoRun
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kNotification_NetworkStatusChanged object:nil];
}
// 网络状态变化
- (void)networkStateChange:(NSNotification*)aNoti
{
    if (![NetStatusManager networkStatusNetwork])
    {
        [[self downloadManager] pause];
    }
    else if ([NetStatusManager networkStatusWifi])
    {
        [[self downloadManager] resume];
    }
    else if ([NetStatusManager networkStatusWWAN])
    {
        // do nothing
    }
}

#pragma mark 访问记录
+(NSString*)cacheKeyOfVisitedIds
{
    return [NSString stringWithFormat:@"visited_ids_%@",NSStringFromClass(self)];
}

-(void)visitItemId:(NSString*)itemId
{
    if (itemId.length == 0) {
        return ;
    }
    
#define kMaxVisitNum    10
    // 从缓存中取出已访问的
    NSArray* array = [CacheDB valueArrayForKey:[[self class] cacheKeyOfVisitedIds]];
    NSMutableArray* mutableArray = [NSMutableArray arrayWithCapacity:0];
    // 如果有缓存，则剔除其中相同的itemId
    if (array) {
        [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            NSString* preItemId = obj;
            if (![itemId isEqualToString:preItemId]) {
                // 剔除相同的攻略id
                [mutableArray addObject:preItemId];
            }
        }];
    }
    
    // 将itemId加到头部
    [mutableArray insertObject:itemId atIndex:0];
    
    // 如果超过记录的最大数量，则清除掉较老的数据
    NSInteger needDeleteNum = mutableArray.count - kMaxVisitNum;
    if (needDeleteNum > 0) {
        for (int iCnt = 0; iCnt < needDeleteNum; iCnt++) {
            [mutableArray removeLastObject];
        }
    }
    
    // 缓存到数据库中
    [CacheDB setValueArray:mutableArray forKey:[[self class] cacheKeyOfVisitedIds]];
}
/** 获取最近访问过的id列表 */
-(NSArray*)getListVisitedIds
{
    NSArray* arrayId = [CacheDB valueArrayForKey:[[self class] cacheKeyOfVisitedIds]];
    return arrayId;
}



#pragma mark ------ 内部接口

- (void)handlerNotificationPercentChanged:(NSNotification *)notify
{
    // 判断是否是自己的下载
    MFWDownloadManager *manager = notify.object;
    if (manager != [self downloadManager]) {
        return;
    }
    
    NSUInteger index = ((NSNumber*)[notify.userInfo valueForKey:MFW_DOWNLOAD_NOTIFY_INDEX_KEY]).unsignedIntegerValue;
    NSString *itemId = [manager getUUIDByIndex:index];
    
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    [center postNotificationName:[[self class] notificationOfDownloadPercentChanged]
                          object:self
                        userInfo:@{kNotificationUserInfoKeyId:itemId}];
}

- (void)handlerNotificationDownloadChanged:(NSNotification*)notify
{
    // 判断是否是自己的下载
    MFWDownloadManager *manager = notify.object;
    if (manager != [self downloadManager]) {
        return;
    }
    
    NSUInteger index = ((NSNumber*)[notify.userInfo valueForKey:MFW_DOWNLOAD_NOTIFY_INDEX_KEY]).unsignedIntegerValue;
    NSString *itemId = [manager getUUIDByIndex:index];
    
    // 当前完成状态解析
    NSNumber *indexNumber = [notify.userInfo valueForKey:MFW_DOWNLOAD_NOTIFY_INDEX_KEY];
    MFWDownloadState state = [[self downloadManager] getStateByIndex:indexNumber.unsignedIntegerValue];
    if (state == MFWDownloadTaskStateFinished)
    {
        // 开始安装
        [self startInstallItemWithId:itemId];
    }else if (state == MFWDownloadTaskStateError){
        // 更新完成状态
        [manager stopByIndex:index];
    }else{
        // 更新完成状态
        [self updateBook:itemId withFinishStatus:ItemFinishStatusNotFinished];
    }
}

- (void)startInstallItemWithId:(NSString*)itemId
{
    [self updateBook:itemId withFinishStatus:ItemFinishStatusNotFinished];
    [self startInstallItemWithId:itemId completion:^(BOOL success, NSError *error) {
        ItemFinishStatus status;
        if (success) {
            status = ItemFinishStatusFinished;
        }else{
            status = ItemFinishStatusError;
        }
        
        // 更新完成状态
        [self updateBook:itemId withFinishStatus:status];
        
        // 移除zip包
//        [[NSFileManager defaultManager] removeItemAtPath:kFile_BOOK_DOWN_PKG(itemId) error:nil];
//        [[NSFileManager defaultManager] removeItemAtPath:[self downloadPathFile:itemId] error:nil];
    }];
}


-(void)updateBook:(NSString*)itemId withFinishStatus:(ItemFinishStatus)status
{
    // 更新将完成状态更新到数据库中
    [self updateDBWithItemId:itemId finishStatus:status];
    
    // 通知攻略状态变化
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    [center postNotificationName:[[self class] notificationOfItemStatusChanged]
                          object:self
                        userInfo:@{kNotificationUserInfoKeyId:itemId}];
    
    if (status == ItemFinishStatusError) {
        // todo 发生错误，可以考虑重试一次或多次，例如等待10秒钟重新下载
    }
}

- (void)updateDBWithItemId:(NSString*)aBookID finishStatus:(ItemFinishStatus)state
{
    // 更新将完成状态更新到数据库中
    [[DBEngine sharedInstance].databaseQueue inDatabase:^(FMDatabase *db) {
        [DBHelper executeUpdateTable:[self downloadTableName]
                                c_id:aBookID
              withColumnKeyValueDict:@{kTableColumn_base_down_c_finish:[NSString stringWithFormat:@"%d",state]}
                            database:db];
    }];
}



#pragma mark



#pragma mark ------ 攻略下载

#pragma mark 获取本地数据


/** 获取下载列表 */
-(NSArray*)getListDownload
{
    __block NSArray* arrayItem = nil;

    [[DBEngine sharedInstance].databaseQueue inDatabase:^(FMDatabase *db) {
        @try {
            // 按创建时间倒排序
            FMResultSet* result = [DBHelper executeSelectTable:[self downloadTableName]
                                                   columnNames:nil
                                                    filterDict:nil
                                                       orderBy:kTableColumn_base_c_ctime
                                                          desc:YES
                                                      database:db];
            arrayItem = [result arrayOfItemClass:[self classOfItem]];
        }
        @catch (NSException *exception) {
            // todo 异常处理
        }
        @finally {

        }
    }];
    
    return arrayItem;
}


/** 获取下载时的Item数据 */
-(id)getItem:(NSString*)itemId
{
    // 参数非法，直接返回
    if (itemId.length == 0) {
        return nil;
    }
    
    __block NSArray* arrayItem = nil;

    [[DBEngine sharedInstance].databaseQueue inDatabase:^(FMDatabase *db) {
        @try {
            FMResultSet* result = [DBHelper executeSelectTable:[self downloadTableName]
                                                         c_ids:@[itemId]
                                                      database:db];
            arrayItem = [result arrayOfItemClass:[self classOfItem]];
        }
        @catch (NSException *exception) {
            // todo 异常处理
        }
        @finally {

        }
    }];
    
    if(arrayItem.count > 0){
        return [arrayItem lastObject];
    }else{
        return nil;
    }
}



///** 按关键词获取book列表：本地下载列表（BookItem的数据可能比BookModel里的老）*/
//-(NSArray*)getListDownloadByKeyword:(NSString*)keyword
//{
//    NSArray* listAll = [self getListDownload];
//    if (keyword.length == 0) {
//        // 关键词为空，返回全部
//        return listAll;
//    }
//    
//    NSMutableArray* listByKeyword = [NSMutableArray arrayWithCapacity:0];
//    [listAll enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
//        BaseItemWithDownload* item = obj;
//        if ([item.title rangeOfString:keyword].location != NSNotFound) {
//            [listByKeyword addObject:obj];
//        }
//    }];
//    
//    return listByKeyword;
//}


#pragma mark 下载控制


/** 将攻略添加到下载列表中 */
-(BOOL)itemDownloadAdd:(NSString*)itemId
{
    if (itemId.length == 0) {
        return NO;
    }
    
    // 已经添加过了，就不用再添加了
    if ([self itemFinishStatus:itemId] != ItemFinishStatusNotExist) {
        return YES;
    }
    
    BaseItemWithDownload* item = [self cacheCenterItemById:itemId];
    if(!item)
    {
        // 未找到此攻略数据
        return NO;
    }
    
    __block BOOL succeeded = YES;

    // 添加到数据库下载表中，将完成状态设置为未完成
    [[DBEngine sharedInstance].databaseQueue inDatabase:^(FMDatabase *db) {
        NSDictionary* extraDict = [self dbExtraDict:item];
        
        NSMutableDictionary* allExtraDict = [NSMutableDictionary dictionaryWithDictionary:extraDict];
        [allExtraDict addEntriesFromDictionary:@{
                                                 kTableColumn_base_down_ver:item.ver
                                                 ,kTableColumn_base_down_title:item.title
                                                 ,kTableColumn_base_down_c_finish:[NSString stringWithFormat:@"%d",ItemFinishStatusNotFinished]}];
        
        succeeded = [DBHelper executeInsertOrUpdateTable:[self downloadTableName]
                                                    c_id:itemId
                                                  c_json:JsonEncode(item.originDict)
                                  withColumnKeyValueDict:allExtraDict
                                                database:db];
    }];
    
    // 开始下载
    succeeded = succeeded && [self itemDownloadStart:itemId];
    
    if (succeeded)
    {
        [[NSNotificationCenter defaultCenter] postNotificationName:[[self class] notificationOfDownloadAdded]
                                                            object:nil
                                                          userInfo:@{kNotificationUserInfoKeyId:itemId}];
        
        // 通知攻略状态变化
        NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
        [center postNotificationName:[[self class] notificationOfItemStatusChanged]
                              object:self
                            userInfo:@{kNotificationUserInfoKeyId:itemId}];
    }
    
    return succeeded;
}



/** 更新下载（会删除已下载）*/
- (BOOL)itemDownloadUpdate:(NSString*)itemId
{
    BOOL succeeded = YES;
    // 从现有下载里移除
    succeeded = succeeded && [self itemDownloadRemove:itemId];
    
    // 重新添加
    succeeded = succeeded && [self itemDownloadAdd:itemId];
    
    return succeeded;
}

/** 下载开始 */
- (BOOL)itemDownloadStart:(NSString*)itemId
{
    // 创建此攻略的目录
//    NSString* bookDownPath = kPATH_BOOK_DOWN(itemId);
    NSString* bookDownPath = [self downloadPath:itemId];
    if(![[NSFileManager defaultManager] fileExistsAtPath:bookDownPath])
    {
        [[NSFileManager defaultManager] createDirectoryAtPath:bookDownPath withIntermediateDirectories:YES attributes:nil error:nil];
    }
    
    BaseItemWithDownload *item = [self getItem:itemId];
    MFWDownloadManager *manager = [self downloadManager];
    
    NSUInteger existIndex = [manager getIndexByUrl:item.file];
    // 在下载库中有对应任务
    if (existIndex < [manager getCount]){   // 判断是否合法
        // 任务是完成状态
        if ([manager getStateByIndex:existIndex] == MFWDownloadTaskStateFinished) {
//            if ([[NSFileManager defaultManager] fileExistsAtPath:kFile_BOOK_DOWN_PKG(itemId)]) {
            if ([[NSFileManager defaultManager] fileExistsAtPath:[self downloadPathFile:itemId]]) {
                // 有文件，则开始安装过程
                [self startInstallItemWithId:itemId];
            }else{
                // 如果指定位置没有文件，则应该先删除下载库中的任务，再重新开始下载
                [manager deleteByIndex:existIndex ifFinishedDeleteFile:YES];
            }
        }
    }
    
    [manager startDownloadFile:item.file
                 withLocalPath:[self downloadPathFile:itemId]
                         andID:itemId];
    return YES;
}
/** 下载暂停 */
-(BOOL)itemDownloadPause:(NSString *)itemId
{
    NSUInteger index = [[self downloadManager] getIndexByUUID:itemId];
    [[self downloadManager] stopByIndex:index];
    return YES;
}
/** 下载移除 */
-(BOOL)itemDownloadRemove:(NSString*)itemId
{
    // 参数异常，直接返回
    if (itemId.length == 0) {
        return NO;
    }
    
    __block BOOL succeeded = NO;
    
    // 从数据库中删除
    [[DBEngine sharedInstance].databaseQueue inDatabase:^(FMDatabase *db) {
        succeeded = [DBHelper executeDeleteTable:[self downloadTableName] filterDict:@{kTableColumn_base_c_id:itemId} database:db];
    }];
    
    NSError* error = nil;
    NSUInteger index = [[self downloadManager] getIndexByUUID:itemId];
    [[self downloadManager] deleteByIndex:index ifFinishedDeleteFile:NO];
    
    
    // 删除此Item的本地目录
    NSString* path = [self downloadPath:itemId];
    NSFileManager* fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:path]) {
        [fileManager removeItemAtPath:path error:&error];
    }
    
    if (!error && succeeded) {
        return YES;
    }else{
        return NO;
    }
}


#pragma mark 下载状态

/** Step 1 : 攻略状态 */
-(ItemStatus)itemStatus:(NSString*)itemId
{
    ItemStatus itemStatus = ItemStatusNotExist;
    
    ItemFinishStatus finishStatus = [self itemFinishStatus:itemId];
    switch (finishStatus) {
        case ItemFinishStatusNotExist:
            itemStatus = ItemStatusNotExist;
            break;
        case ItemFinishStatusFinished:
            itemStatus = ItemStatusFinished;
            break;
        case ItemFinishStatusMustUpdate:
            itemStatus = ItemStatusMustUpdate;
            break;
        case ItemFinishStatusError:
            itemStatus = ItemStatusError;
            break;
        default:
            // todo 未知的状态
            break;
    }
    
    if (finishStatus == ItemFinishStatusNotFinished) {
        ItemDownloadStatus downloadStatus = [self itemDownloadStatus:itemId];
        switch (downloadStatus) {
            case ItemDownloadStatusNotExist:
                itemStatus = ItemStatusError; // 如果下载状态是不存在，则认为是错误，需要手动重新下载
                break;
            case ItemDownloadStatusFinished:
                itemStatus = ItemStatusInstalling;
                break;
            case ItemDownloadStatusDownloading:
                itemStatus = ItemStatusDownloading;
                break;
            case ItemDownloadStatusWaiting:
                itemStatus = ItemStatusWaiting;
                break;
            case ItemDownloadStatusPaused:
                itemStatus = ItemStatusPaused;
                break;
            case ItemDownloadStatusError:
                itemStatus = ItemStatusError;
                break;
            default:
                // todo 未知的状态
                break;
        }
    }
    
    return itemStatus;
}

/** 攻略完成状态（不存在、未完成、已完成、必须更新）*/
-(ItemFinishStatus)itemFinishStatus:(NSString*)itemId
{
    __block ItemFinishStatus finishStatus = ItemFinishStatusNotExist;
    [[DBEngine sharedInstance].databaseQueue inDatabase:^(FMDatabase *db) {
        FMResultSet* result = [DBHelper executeSelectTable:[self downloadTableName] columnNames:@[kTableColumn_base_down_c_finish] filterDict:@{kTableColumn_base_c_id:itemId} orderBy:nil desc:NO database:db];

        while ([result next]) {
            finishStatus = [result intForColumn:kTableColumn_base_down_c_finish];
        }
    }];
    
    return finishStatus;
}


/** 攻略下载状态 */
-(ItemDownloadStatus)itemDownloadStatus:(NSString*)itemId
{
    MFWDownloadManager *manager = [self downloadManager];
    NSUInteger index = [manager getIndexByUUID:itemId];
    if (index >= [manager getCount])
    {
        return ItemDownloadStatusNotExist;
    }
    MFWDownloadState state = [manager getStateByIndex:index];
    ItemDownloadStatus downloadStatus = ItemDownloadStatusNotExist;
    switch (state) {
        case MFWDownloadTaskStateError:
            downloadStatus = ItemDownloadStatusError;
            break;
        case MFWDownloadTaskStateFinished:
            downloadStatus = ItemDownloadStatusFinished;
            break;
        case MFWDownloadTaskStateRunning:
            downloadStatus = ItemDownloadStatusDownloading;
            break;
        case MFWDownloadTaskStateWaiting:
            downloadStatus = ItemDownloadStatusWaiting;
            break;
        default:
            downloadStatus = ItemDownloadStatusPaused;
            break;
    }
    
    return downloadStatus;
}

/** 攻略是否需要升级 */
-(BOOL)itemDownloadNeedUpdate:(NSString*)itemId
{
    if([self itemStatus:itemId] == ItemStatusMustUpdate)
    {
        // 迁移过来的必须更新的
        return YES;
    }
    
    BaseItemWithDownload* item = [self cacheCenterItemById:itemId];
    BaseItemWithDownload* downItem = [self getItem:itemId];
    
    // 有最新的攻略，且我的下载里的攻略版本号与之不同，则需要更新
    if ([item.ver integerValue] - [downItem.ver integerValue] > [item.num_skip_version integerValue]) {
        return YES;
    }else{
        return NO;
    }
}

/** 下载进度 */
-(float)itemDownloadPercent:(NSString*)itemId
{
    NSUInteger index = [[self downloadManager] getIndexByUUID:itemId];
    MFWDownloadProgress progress = [[self downloadManager] getProgressByIndex:index];
    return progress.percent;
}





#pragma mark 一键更新

/** （本地）更新全部：重新下载需更新的攻略 */
-(NSInteger)itemDownloadUpdateAll
{
    __block NSInteger countSuccess = 0;
    
    NSArray* array = [self itemDownloadCheckUpdateLocal];
    [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        BaseItemWithDownload* item = obj;
        if ([self itemDownloadUpdate:item.id]) {
            countSuccess++;
        }
    }];
    
    return countSuccess;
}

/** （本地）获取下载列表中需更新的 */
-(NSArray*)itemDownloadCheckUpdateLocal
{
    NSMutableArray* items = [NSMutableArray arrayWithCapacity:0];
    NSArray* array = [self getListDownload];
    [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        BaseItemWithDownload* item = obj;
        if ([self itemDownloadNeedUpdate:item.id]) {
            [items addObject:item];
        }
    }];
    
    return items;
}

/** （在线）获取下载列表中需更新的 */
-(void)itemDownloadCheckUpdateOnlineCompletion:(void(^)(NSArray* listItemNeedUpdate))completion
{
    NSMutableArray* ids = [NSMutableArray arrayWithCapacity:0];
    NSArray* array = [self getListDownload];
    [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        BaseItemWithDownload* item = obj;
//        if ([self itemDownloadNeedUpdate:item.id]) {
            [ids addObject:item.id];
//        }
    }];
    
    [self requestListByIds:ids completion:^(NSArray *listItem) {
        if (completion) {
            // 和本地比较，返回需更新数量
            completion([self itemDownloadCheckUpdateLocal]);
        }
    }];
}


- (void)refreshAllDownloadListItem
{
    NSString* userInfoKey = NSStringFromClass([self class]);
    
    NSUserDefaults *defauts = [NSUserDefaults standardUserDefaults];
    // 最后更新时间
    NSString *lastUpdate = [defauts valueForKey:userInfoKey];
    
    // 当前时间
    NSDateFormatter *format = [[NSDateFormatter alloc] init];
    [format setDateFormat:@"yyyyMMdd"];
    NSString *dateString = [format stringFromDate:[NSDate date]];
    if ([lastUpdate isEqualToString:dateString])
    {
        return;
    }
    
    // 记录最后更新时间
    [defauts setValue:dateString forKey:userInfoKey];
    [defauts synchronize];
    
    // 更新列表
    NSArray *items= [self getListDownload];
    NSMutableArray *arr = [[NSMutableArray alloc] init];
    for (BaseItemWithDownload *item in items)
    {
        [arr addObject:item.id];
    }
    
    [self requestListByIds:arr completion:nil];
}

#pragma mark 下载统计

/** 当前攻略下载总数（含未完成）*/
-(NSInteger)itemDownloadCountTotal
{
    __block NSInteger count = 0;
    
    [[DBEngine sharedInstance].databaseQueue inDatabase:^(FMDatabase *db) {
        @try {
            // 按创建时间倒排序
            count = [DBHelper executeCountTable:[self downloadTableName] filterDict:nil database:db];
        }
        @catch (NSException *exception) {
            // todo 异常处理
        }
        @finally {

        }
    }];
    
    return count;
}



@end
